package crp.services.api.graphql.loaders;

import com.qwlabs.lang.C2;
import crp.core.course.domain.models.CourseEntity;
import crp.core.portal.app.PortalSectionService;
import crp.core.portal.domain.models.PortalSectionCourseLoadContext;
import crp.core.shared.PublicStatus;
import crp.services.api.graphql.models.CoursePayload;
import crp.services.api.graphql.models.PortalSectionPayload;
import org.eclipse.microprofile.graphql.GraphQLApi;
import org.eclipse.microprofile.graphql.Source;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@GraphQLApi
@RequestScoped
public class PortalSectionPayloadLoader {
    private final PortalSectionService portalSectionService;

    @Inject
    public PortalSectionPayloadLoader(PortalSectionService portalSectionService) {
        this.portalSectionService = portalSectionService;
    }

    @NotNull
    public List<@NotNull List<@NotNull CoursePayload>> courses(
            @Source List<PortalSectionPayload> sections,
            Integer limit) {
        PortalSectionCourseLoadContext context = new PortalSectionCourseLoadContext(
                C2.list(sections, payload -> new PortalSectionCourseLoadContext.SectionWithConfig(payload.getId(), payload.getConfig())),
                limit,
                C2.set(PublicStatus.values())
        );
        Map<String, List<CourseEntity>> sectionCourses = portalSectionService.courseLoader().load(context);
        return C2.list(sections, section ->
                C2.stream(sectionCourses.getOrDefault(section.getId(), List.of()))
                        .map(CoursePayload::of)
                        .collect(Collectors.toList()));
    }

    @NotNull
    public List<@NotNull List<@NotNull CoursePayload>> publicCourses(
            @Source List<PortalSectionPayload> sections,
            Integer limit) {
        PortalSectionCourseLoadContext context = new PortalSectionCourseLoadContext(
                C2.list(sections, payload -> new PortalSectionCourseLoadContext.SectionWithConfig(payload.getId(), payload.getConfig())),
                limit,
                Set.of(PublicStatus.PUBLIC)
        );
        Map<String, List<CourseEntity>> sectionCourses = portalSectionService.courseLoader().load(context);
        return C2.list(sections, section ->
                C2.stream(sectionCourses.getOrDefault(section.getId(), List.of()))
                        .map(CoursePayload::of)
                        .collect(Collectors.toList()));
    }
}
